package com.songlanyun.modules.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.HouniaoConstant;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.supplychainapi.order.ApiOrderCommon;
import com.songlanyun.common.supplychainapi.order.model.Address;
import com.songlanyun.common.supplychainapi.order.model.CheckParam;
import com.songlanyun.common.supplychainapi.order.model.Spu;
import com.songlanyun.common.utils.HouniaoApiUtil;
import com.songlanyun.common.utils.OrderGen;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.UserShopRoleEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.UserShopRoleService;
import com.songlanyun.modules.category.entity.SystemProductCategoryEntity;
import com.songlanyun.modules.coupon.entity.CouponReceiveRecordEntity;
import com.songlanyun.modules.coupon.service.CouponReceiveRecordService;
import com.songlanyun.modules.coupon.service.CouponService;
import com.songlanyun.modules.exception.GoodsExceptionEnum;
import com.songlanyun.modules.exception.OrderException;
import com.songlanyun.modules.freighttemplate.entity.FreightTemplate;
import com.songlanyun.modules.freighttemplate.service.FreightTemplateService;
import com.songlanyun.modules.goods.entity.Goods;
import com.songlanyun.modules.goods.entity.GoodsAuthShop;
import com.songlanyun.modules.goods.entity.GoodsSku;
import com.songlanyun.modules.goods.service.GoodsService;
import com.songlanyun.modules.goods.service.GoodsSkuService;
import com.songlanyun.modules.inter.ISaleEntity;
import com.songlanyun.modules.logisticsconfig.entity.LogisticsConfig;
import com.songlanyun.modules.logisticsconfig.service.LogisticsConfigService;
import com.songlanyun.modules.memberbill.entity.GiveBalanceDTO;
import com.songlanyun.modules.order.dao.OrderDao;
import com.songlanyun.modules.order.entity.*;
import com.songlanyun.modules.order.model.dto.*;
import com.songlanyun.modules.order.model.vo.*;
import com.songlanyun.modules.order.service.*;
import com.songlanyun.modules.payorder.entity.PayOrder;
import com.songlanyun.modules.payorder.service.PayOrderService;
import com.songlanyun.modules.shop.entity.ShopEntity;
import com.songlanyun.modules.shop.entity.ShopUserRoleConfigEntity;
import com.songlanyun.modules.shop.service.ShopService;
import com.songlanyun.modules.shop.service.ShopUserRoleConfigService;
import com.songlanyun.modules.useraddress.entity.UserAddress;
import com.songlanyun.modules.useraddress.service.UserAddressService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 所有商品下单构单入口
 */
@Service("createOrderService")
public class CreateOrderServiceImpl extends ServiceImpl<OrderDao, Order> implements CreateOrderService {

    @Autowired
    private LogisticsConfigService logisticsConfigService;
    @Autowired
    private ShopService shopService;

    @Autowired
    private FreightTemplateService freightTemplateService;


    @Autowired
    private AccountService accountService;

    @Autowired
    private UserShopRoleService userShopRoleService;

    @Autowired
    private ShopUserRoleConfigService shopUserRoleConfigService;


    @Autowired
    private OrderReceiptService orderReceiptService;

    @Autowired
    private OrderSelfTakeService orderSelfTakeService;

    @Autowired
    private OrderBusinessKeyService orderBusinessKeyService;

    @Autowired
    private OrderUserKeyService orderUserKeyService;


    @Autowired
    private OrderService orderService;

    @Autowired
    private UserAddressService userAddressService;


    @Resource(name="commonCreateOrderService")
    private CreateOrderService commonCreateOrderService;

    @Resource(name="serviceGoodsCreateOrderService")
    private CreateOrderService serviceGoodsCreateOrderService;

    @Resource(name="groupGoodsCreateOrderService")
    private CreateOrderService groupGoodsCreateOrderService;

    @Resource(name="seckillGoodsCreateOrderService")
    private CreateOrderService seckillGoodsCreateOrderService;


    @Resource(name="pointGoodsCreateOrderService")
    private CreateOrderService pointGoodsCreateOrderService;

    @Resource(name="freeReceiveGoodsCreateOrderService")
    private CreateOrderService freeReceiveGoodsCreateOrderService;


    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private ChildOrderService childOrderService;


    @Autowired
    private CouponReceiveRecordService couponReceiveRecordService;


    @Autowired
    private CouponService couponService;

    @Autowired
    private ApiOrderCommon apiOrderCommon;

    @Autowired
    private HouniaoApiUtil houniaoApiUtil;

    @Resource(name="createOrderService")
    private CreateOrderService createOrderService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private GoodsSkuService goodsSkuService;


    /**
     * 构建下单页数据
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    public SubmitOrderVo buildSubmitOrder(Long userId, SubmitOrderDTO dto) {

        if (dto.getOrderType() == 1) {
            switch (dto.getMarketingType()) {
                case 1:
                    /**
                     * 秒杀订单
                     */
                    return seckillGoodsCreateOrderService.buildSubmitOrder(userId, dto);
                case 2:
                    /**
                     * 拼团订单
                     */
                    return groupGoodsCreateOrderService.buildSubmitOrder(userId, dto);

                default:
                    //免费领
//                    if(dto.getFree())
//                    {
//                        return freeReceiveGoodsCreateOrderService.buildSubmitOrder(userId, dto);
//                    }
                    /**
                     * 普通订单(含有积分抵扣商品)
                     */
                    if(!dto.getPointGoods())
                    {
                        return commonCreateOrderService.buildSubmitOrder(userId, dto);
                    }
                    else
                    {
                        return pointGoodsCreateOrderService.buildSubmitOrder(userId, dto);
                    }

            }
        } else {
            return serviceGoodsCreateOrderService.buildSubmitOrder(userId, dto);

        }
    }


    /**
     * 会员下单服务
     *
     * @param userId
     * @param dto
     * @return
     */

    @Transactional
    @Override
    public PayOrder createPayOrder(Long userId, SubmitOrderDTO dto) {

        PayOrder  payOrder = null;
        if (dto.getOrderType() == 1) {
            switch (dto.getMarketingType()) {
                case 1:
                    /**
                     * 秒杀订单
                     */
                    payOrder =  seckillGoodsCreateOrderService.createPayOrder(userId, dto);
                    break;
                case 2:
                    /**
                     * 拼团订单
                     */
                    payOrder =  groupGoodsCreateOrderService.createPayOrder(userId, dto);
                    break;

                default:
                    if(!dto.getPointGoods())
                    {
//                        if(dto.getFree())
//                        {
//                            payOrder = freeReceiveGoodsCreateOrderService.createPayOrder(userId, dto);
//                        }
//                        else {
//                            payOrder = commonCreateOrderService.createPayOrder(userId, dto);
//                        }
                        payOrder = commonCreateOrderService.createPayOrder(userId, dto);
                    }
                    else
                    {
                        payOrder =   pointGoodsCreateOrderService.createPayOrder(userId, dto);
                    }
                    break;
            }



        } else {
            payOrder =  serviceGoodsCreateOrderService.createPayOrder(userId, dto);

        }

        /**
         * 只要是支付订单中的钱是0,订单支付完成，如果是积分订单，在下单时就已扣除了积分
         */
        if(payOrder.getTotalAmount().compareTo(BigDecimal.ZERO)==0)
        {
            OrderConstant.PayMode payMode = payOrder.getPointGoods()?OrderConstant.PayMode.POINT:OrderConstant.PayMode.BALANCE;
            payOrder = payOrderService.paymentHandle(payOrder.getCode(), "", BigDecimal.ZERO, payMode);
        }

        if (dto.getOrderType() == 1)
        {
            //下单扣库存===============================================================
            List<ChildOrder> allChildList = new ArrayList<>();
            payOrder.loadOrders().forEach(o->{
                allChildList.addAll(o.getChildOrderList(true));
            });

            allChildList.sort(Comparator.comparing(ChildOrder::getSingleGoodsId));
            childOrderService.processBatchSingleGoodsStock(allChildList);
        }
        return payOrder;
    }

    @Override
    public void thirdCanSaleCheck(SubmitOrderVo vo) {

        Address address = Address.builder()
                .province(vo.getReceipt().getProvinceName())
                .city(vo.getReceipt().getCityName())
                .area(vo.getReceipt().getAreaName())
                .description(vo.getReceipt().getAddress())
                .street(" ")
                .consignee(vo.getReceipt().getReceiver())
                .phone(vo.getReceipt().getMobile())
                .build();
        for(SubmitShopOrderVo submitShopOrderVo:vo.getShopOrders()) {
            if (submitShopOrderVo == null) continue;
            // 原版app逻辑
            if(submitShopOrderVo.getThird() && !Objects.equals(submitShopOrderVo.getSource(),  99)) {
                List<SubmitChildOrderVo> items = submitShopOrderVo.getItems();
                Spu[] spuArray = items.stream().map(o -> Spu.builder()
                        .sku(o.getThirdSkuId())
                        .number(o.getNum())
                        .build()).toArray(Spu[]::new);

                CheckParam build = CheckParam.builder()
                        .address(address)
                        .spu(spuArray)
                        .build();
                // app原版可售检测
                apiOrderCommon.availableCheck(build);
            }
        }


    }

    /**
     * 内部调用初始化订单的基础数据================================================
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    public SubmitOrderVo initSubmitOrderVo(Long userId, SubmitOrderDTO dto) {
        //下单时一定要选择店铺====================================================
        if (dto.getShopOrders().size() == 0) {
            throw new RRException(OrderException.ORDER_NOT_SHOP);
        }

        SubmitOrderVo vo = new SubmitOrderVo();
        vo.setPointGoods(dto.getPointGoods());
        vo.setOrderType(dto.getOrderType());
        //活动内类型设置
        vo.setMarketingType(dto.getMarketingType());
        vo.setUserId(userId);
        //客户端设置
        vo.setChanelType(dto.getChanelType());
        //是否是来源购物车
        vo.setIsCart(dto.getIsCart());
        //设置物流模式
        vo.setShipmentMode(dto.getShipmentMode());

        vo.setServiceSystemGoods(dto.getServiceSystemGoods());
        UserAddress userAddress = null;
        if(dto.getOrderType()==1) {
            //如果是快递物流
            if (dto.getShipmentMode() == 0) {
                vo.setReceipt(new SubmitOrderReceiptVo());
                if (dto.getReceiptId() == null) {
                    //如果没有给收货地址，取会员默认的
                    userAddress = userAddressService.getDefaultByUserId(userId);
                } else {
                    //如果给了收货地址，查对应的收货地址
                    userAddress = userAddressService.getByUserIdAndId(userId, dto.getReceiptId());
                }
                if (userAddress != null) {
                    BeanUtils.copyProperties(userAddress, vo.getReceipt());

                    vo.getReceipt().setMobile(userAddress.getPhone());
                    vo.getReceipt().setReceiver(userAddress.getName());
                }

            } else {
                //如果自提模式
                vo.setSelfTake(new SubmitOrderSelfTakeVo());
                if (dto.getSelfTake() != null) {
                    BeanUtils.copyProperties(dto.getSelfTake(), vo.getSelfTake());
                }

            }


            //是否可以选择自提=============================================================
            //如果是多店一起下单不能选择自提
            if (dto.getShopOrders().size() > 1) {
                //说明要从购物车来的
                vo.setIsAbleSelectSelfTake(false);
            } else {
                //否则根据商家设置来确定是否可以选择自提
                SubmitShopOrderDTO submitShopOrderDTO = dto.getShopOrders().get(0);
                LogisticsConfig logisticsConfig = logisticsConfigService.getLogisticsConfig(submitShopOrderDTO.getShopId());
                if (logisticsConfig == null || !logisticsConfig.getAblePickup()) {
                    //如果没有开通自提
                    vo.setIsAbleSelectSelfTake(false);
                } else {
                    //如果开通自提
                    vo.setIsAbleSelectSelfTake(true);
                    ShopEntity shopEntity = shopService.loadShopBy(submitShopOrderDTO.getShopId(), true);
                    vo.setSelfTakeShop(shopEntity);
                }
            }

            computePlatformCoupon(userId,vo,dto);
        }

        return vo;
    }




    /**
     * 重构初始化构造提交商家订单vo
     *
     * @param userId
     * @param dto
     * @param o
     * @return
     */
    @Override
    public SubmitShopOrderVo initBuildSubmitShopOrderVo(Long userId, SubmitOrderDTO dto, SubmitShopOrderDTO o) {
        //计算每个店铺订单中的商品明细数据=============================================================
        //下单时一定选择商品
        if (o.getItems().size() == 0) {
            throw new RRException(OrderException.ORDER_NOT_GOODS);
        }
        SubmitShopOrderVo shopOrderVo = new SubmitShopOrderVo();
        shopOrderVo.setOrderType(dto.getOrderType());
        shopOrderVo.setMarketingType(dto.getMarketingType());

        ShopEntity shop = shopService.loadShopBy(o.getShopId(), true);
        shopOrderVo.setShopId(shop.getId());
        shopOrderVo.setShopName(shop.getShopName());
        shopOrderVo.setUserRemark(o.getUserRemark());
        shopOrderVo.setSourceShopId(o.getSourceShopId());
        shopOrderVo.setSourceShopName(shop.getShopName());
        if (!o.getSourceShopId().equals(o.getShopId())) {
            ShopEntity sourceShop = shopService.loadShopBy(o.getSourceShopId(), true);
            shopOrderVo.setSourceShopName(sourceShop.getShopName());
        }
        shopOrderVo.setPlatformShop(shop.getPlatformShop());

        //查询会员在当前门店订单中的等级
        UserShopRoleEntity userShopRole = userShopRoleService.getUserShopRole(o.getShopId(), userId);
        if (userShopRole == null) {
            //如果没有取默认等级
            ShopUserRoleConfigEntity byShopIdAndLevel = shopUserRoleConfigService.getByShopIdAndLevel(o.getShopId(), 0);
            shopOrderVo.setUserRoleCode(byShopIdAndLevel.getRoleCode());
            shopOrderVo.setUserRoleName(byShopIdAndLevel.getRoleName());
        } else {
            shopOrderVo.setUserRoleCode(userShopRole.getRoleCode());
            shopOrderVo.setUserRoleName(userShopRole.getRoleName());
        }

        shopOrderVo.setShopCoupon(o.getShopCoupon());

        shopOrderVo.setServiceSystemGoods(dto.getServiceSystemGoods());
        return shopOrderVo;
    }


    /**
     * 重构初始化构造提交商家子订单vo
     *
     * @param saleEntity
     * @param dto
     * @param o
     * @param s
     * @return
     */
    @Override
    public SubmitChildOrderVo initBuildSubmitChildOrderVo(ISaleEntity saleEntity, SubmitOrderDTO dto, SubmitShopOrderDTO o, SubmitChildOrderDTO s) {
        SubmitChildOrderVo childOrderVo = new SubmitChildOrderVo();
        childOrderVo.setOrderType(dto.getOrderType());
        Goods goods = (Goods) saleEntity;
        if (!goods.isVerify()) {
            //商品审核不通过
            throw new RRException(GoodsExceptionEnum.GOODS_VERIFY_NOT);
        }

        //判定当前来源店是否有商品的经营权限
        GoodsAuthShop goodsAuthShop = goods.loadAuthByShop(o.getSourceShopId());
        if (goodsAuthShop == null) {
            //不具备经营权限
            throw new RRException(GoodsExceptionEnum.NOT_PROXY_AUTH);
        }
        if (!goodsAuthShop.isAdded()) {
            //商品未上架
            throw new RRException(GoodsExceptionEnum.GOODS_NOT_ADDED);
        }


        childOrderVo.setUserCartId(s.getUserCartId());
        childOrderVo.setGoodsId(goods.getId());
        childOrderVo.setGoodsTitle(goods.getTitle());
        childOrderVo.setGoodsShortTitle(goods.getShortTitle());
        childOrderVo.setProxyGoods(goods.getAbleProxySale());
        childOrderVo.setGiftType(goods.getGiftType());
        childOrderVo.setFreightTemplateId(goods.getFreightTemplateId());
        //如果是下的活动订单这里要设置活动商品
        childOrderVo.setActivityGoodsId(s.getActivityGoodsId());
        childOrderVo.setGoodsCover(goods.getCover());
        childOrderVo.setNum(s.getNum());
        childOrderVo.setThird(goods.getThird());
        childOrderVo.setThirdSpuId(goods.getThirdSpuId());
        childOrderVo.setSource(goods.getSource());
        childOrderVo.setHouniaoSpuId(goods.getHouniaoSpuId());

        SystemProductCategoryEntity systemProductCategoryEntity = goods.loadCategory();
        if(ObjectUtil.isNotNull(systemProductCategoryEntity)) {
            Long parentId = systemProductCategoryEntity.getParentId();
            childOrderVo.setFirstCategoryId(parentId.equals(0L) ? goods.getCategoryId() : parentId);
            childOrderVo.setGoodsCategoryId(goods.getCategoryId());
        }
        else
        {
            childOrderVo.setFirstCategoryId(0L);
            childOrderVo.setGoodsCategoryId(0L);
        }


        return childOrderVo;
    }

    @Override
    public void computeSelectedShopCoupon(Long userId, SubmitShopOrderVo vo, SubmitShopOrderDTO dto) {
        if(dto.getShopCoupon().getMyCouponId()>0L)
        {
            validateMyCouponCanUse(userId, dto.getShopCoupon().getMyCouponId());
            vo.setShopCoupon(SubmitOrderUseCoupon.builder().myCouponId(dto.getShopCoupon().getMyCouponId()).build());
        }
    }

    @Override
    @Transactional
    public void backStageManagement(GiveBalanceDTO dto) {


        SubmitOrderDTO submitOrderDTO = new SubmitOrderDTO();
        submitOrderDTO.setMarketingType(0);
        submitOrderDTO.setChanelType(0);
        submitOrderDTO.setUserId(dto.getUserObjId());
        submitOrderDTO.setShipmentMode(1);

        List<SubmitShopOrderDTO> list = new ArrayList<>();

        SubmitShopOrderDTO submitShopOrderDTO = new SubmitShopOrderDTO();
        submitShopOrderDTO.setShopId(9L);
        submitShopOrderDTO.setSourceShopId(9L);
        submitShopOrderDTO.setActivityId(0L);
        submitShopOrderDTO.setSponsorActivityId(0L);
        submitShopOrderDTO.setUserRemark("");

        List<SubmitChildOrderDTO> submitChildOrderDTOList = new ArrayList<>();
        SubmitChildOrderDTO submitChildOrderDTO = new SubmitChildOrderDTO();
        submitChildOrderDTO.setUserCartId(0L);
        submitChildOrderDTO.setActivityGoodsId(0L);
        submitChildOrderDTO.setGoodsId(dto.getGoodsId());
        submitChildOrderDTO.setNum(1);
        submitChildOrderDTO.setSkuHashCode(goodsSkuService.getOne(new LambdaQueryWrapper<GoodsSku>()
                .eq(GoodsSku::getGoodsId, dto.getGoodsId()
                )).getSkuHashCode());
        submitChildOrderDTOList.add(submitChildOrderDTO);


        submitShopOrderDTO.setItems(submitChildOrderDTOList);
        list.add(submitShopOrderDTO);

        submitOrderDTO.setShopOrders(list);
        submitOrderDTO.setMarketingType(0);
        submitOrderDTO.setFree(false);
        submitOrderDTO.setUsePlatformPoint(true);

        submitOrderDTO.setIsAdminOrder(true);



        // 创建订单
        createOrderService.buildSubmitOrder(dto.getUserObjId(),submitOrderDTO);
        //创建支付订单
        PayOrder creatPayOrder = createOrderService.createPayOrder(dto.getUserObjId(), submitOrderDTO);
        //支付成功后逻辑
        PayOrder payOrder = payOrderService.paymentHandle(creatPayOrder.getCode(), creatPayOrder.getCode(),creatPayOrder.getTotalAmount(), OrderConstant.PayMode.ADMIN_ORDER);

        //修改支付订单状态，为了app中不显示订单
        payOrder.setAdminOrder(true);
        payOrderService.updateById(payOrder);

        //修改主订单状态，为了app中不显示订单
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getPayOrderCode, payOrder.getCode()));
        order.setTransactionStatus(OrderConstant.TransactionStatus.COMPLETE);
        order.setAdminOrder(true);
        orderService.updateById(order);



    }

    private void computePlatformCoupon(Long userId,  SubmitOrderVo vo,SubmitOrderDTO dto) {
        if(dto.getPlatformCoupon().getMyCouponId()>0L)
        {
            validateMyCouponCanUse(userId, dto.getPlatformCoupon().getMyCouponId());
            vo.setPlatformCoupon(SubmitOrderUseCoupon.builder().myCouponId(dto.getPlatformCoupon().getMyCouponId()).build());
        }
    }

    private void validateMyCouponCanUse(Long userId, Long myCouponId) {
        CouponReceiveRecordEntity couponReceiveRecordEntity = couponReceiveRecordService.loadMyCoupon(userId, myCouponId);
        if(ObjectUtil.isNull(couponReceiveRecordEntity))
        {
            throw new RRException("选择的优惠券不合法");
        }

        if(couponReceiveRecordEntity.getUseStatus())
        {
            throw new RRException("已使用的优惠券不能使用");
        }
        if(couponReceiveRecordEntity.isExpire())
        {
            throw new RRException("过期的优惠券不能使用");
        }
    }


    /**
     * 创建订单的钥匙
     *
     * @param order
     */
    @Override
    public void createOrderKey(Order order) {
        //创建会员打开订单钥匙,如果钥匙被“会员删除订单”软删除了，关联的订单在订单列表中就显示不出来了
        OrderUserKey orderUserKey = new OrderUserKey();
        orderUserKey.setDeleted(0);
        orderUserKey.setOrderId(order.getId());
        orderUserKey.setUserId(order.getUserId());
        orderUserKeyService.create(orderUserKey);

        //创建订单的直营店的钥匙，如果钥匙被“直营店商家删除订单”，软删除了，自已管理订单列表中的订单就显示不出来了
        OrderBusinessKey shopKey = new OrderBusinessKey();
        shopKey.setOrderId(order.getId());
        shopKey.setShopId(order.getShopId());
        shopKey.setDeleted(0);
        orderBusinessKeyService.create(shopKey);

        if (order.getProxy() && !order.getShopId().equals(order.getSourceShopId())) {
            //创建订单的代销店的钥匙，如果钥匙被“代销店商家删除订单”，软删除了，自已管理订单列表中的订单就显示不出来了
            //代销店看自己的代销的订单，是只能不能操作
            OrderBusinessKey sourceShopKey = new OrderBusinessKey();
            sourceShopKey.setOrderId(order.getId());
            sourceShopKey.setShopId(order.getSourceShopId());
            sourceShopKey.setDeleted(0);
            orderBusinessKeyService.create(sourceShopKey);
        }
    }


    /**
     * 创建收货地址或自提信息
     *
     * @param order
     * @param vo
     */
    @Override
    public void createOrderReceiving(Order order, SubmitOrderVo vo) {
        switch (order.getShipmentMode())
        {
            case EXPRESS:
                OrderReceipt orderReceipt = new OrderReceipt();
                if (vo.getReceipt() == null) {
                    throw new RRException(OrderException.ORDER_NOT_EXPRESS);
                }
                BeanUtils.copyProperties(vo.getReceipt(), orderReceipt);
                orderReceipt.setOrderId(order.getId());
                orderReceipt.setOrderCode(order.getOrderCode());
                orderReceiptService.create(orderReceipt);
                break;
            case PICK_UP:
                if (vo.getSelfTake() == null) {
                    throw new RRException(OrderException.ORDER_NOT_PICK_UP);
                }
                OrderSelfTake orderSelfTake = new OrderSelfTake();
                BeanUtils.copyProperties(vo.getSelfTake(), orderSelfTake);
                orderSelfTake.setOrderId(order.getId());
                orderSelfTakeService.create(orderSelfTake);
                break;
            default:
                break;
        }
    }


    /**
     * 创建订单
     *
     * @param userId
     * @param payOrder
     * @param submitOrderVo
     * @param vo
     * @return
     */
    @Override
    public Order createOrder(Long userId, PayOrder payOrder, SubmitOrderVo submitOrderVo, SubmitShopOrderVo vo) {
        Order order = new Order();
        order.setRealName(payOrder.getRealName());
        order.setIdNo(payOrder.getIdNo());
        order.setOrderType(OrderConstant.OrderType.getByCode(vo.getOrderType()));
        order.setMarketingType(vo.getMarketingType());
        order.setOrderCode(OrderGen.generateOrderNo());
        order.setDeleted(0);
        order.setShopId(vo.getShopId());
        order.setShopName(vo.getShopName());
        order.setSourceShopId(vo.getSourceShopId());
        order.setSourceShopName(vo.getSourceShopName());
        order.setAutoStockUpLastTime(0L);
        order.setProxy(!vo.getShopId().equals(vo.getSourceShopId()));
        order.setUserId(userId);
        AccountEntity userAccount = accountService.getUserById(userId, true);
        order.setMobile(userAccount.getMobile());
        order.setShipmentMode(OrderConstant.ShipmentMode.getByCode(submitOrderVo.getShipmentMode()));
        order.setShouldFreight(vo.getTotalFreight());
        order.setRealFreight(vo.getTotalFreight());
        order.setGoodsNumber(vo.getGoodsNum());
        order.setGoodsAmount(vo.getTotalGoodsAmount());
        order.setTotalCost(vo.getTotalCost());
        order.setTotalAmount(vo.getTotalAmount());
        order.setOriginalGoodsAmount(vo.getOriginalGoodsAmount());
        //计算总优惠（总优惠包含会员折扣优惠和首单优惠）
        order.setTotalReduced(vo.getTotalReduced());
        order.setFirstOrderReduced(vo.getFirstOrderReduced());

        //是否是积分兑换订单
        order.setExchange(vo.getExchange());

        order.setTotalPoint(vo.getTotalPoint());
        //赠送积分
        order.setFinalGiveBackPoint(vo.getTotalGiveBackPoint());
        //总共需要赠送多少贡献值
        order.setFinalConsumptionValue(vo.getTotalConsumptionValue());
        order.setActivityId(vo.getActivityId());
        order.setActivityTitle(vo.getActivityTitle());
        order.setSponsorActivityId(vo.getSponsorActivityId());

        order.setPayMode(OrderConstant.PayMode.BALANCE);
        order.setUserRemark(vo.getUserRemark());
        order.setBusinessRemark("");
        order.setImportance(1);

        order.setUserRoleCode(vo.getUserRoleCode());
        order.setUserRoleName(vo.getUserRoleName());
        order.setChannelType(OrderConstant.ChannelType.getByCode(submitOrderVo.getChanelType()));
        order.setExpired(false);
        order.setExpiredTime(payOrder.getExpiredPayTime());
        order.setOrderTime(payOrder.getCreateTimeMillis());
        order.setPayTime(0L);
        order.setPayOrderCode(payOrder.getCode());
        order.setPayOrderId(payOrder.getId());
        order.setLastShipTime(0L);
        order.setLastReceiptTime(0L);
        order.setCompleteTime(0L);
        order.setCloseTime(0L);

        order.setTransactionStatus(OrderConstant.TransactionStatus.WAIT_PAYMENT);
        order.setPaymentStatus(OrderConstant.PaymentStatus.NO_PAY);
        order.setCloseMode(OrderConstant.CloseMode.NO);
        order.setShipStatus(OrderConstant.ShipStatus.NO_SHIP);
        order.setReceiptStatus(OrderConstant.ReceiptStatus.NO);
        order.setCommentStatus(OrderConstant.CommentStatus.NO);
        order.setUseStatus(OrderConstant.UseStatus.NO_USE);
        order.setEffective(true);
        order.setThird(vo.getThird());
        if (order.getMarketingType().equals(2)) {
            order.setEffective(false);
        }
        order.setRightsType(OrderConstant.RightsType.NO);
        order.setRightsStatus(OrderConstant.RightsStatus.NO);
        order.setEnd(false);
        order.setActivityId(vo.getActivityId());
        order.setActivityTitle(vo.getActivityTitle());
        order.setServiceSystemGoods(vo.getServiceSystemGoods());
        order.setAreaFeature(vo.getAreaFeature());
        if(vo.getPlatformCoupon().getMyCouponId()>0L)
        {
            order.setPlatformMyCouponId(vo.getPlatformCoupon().getMyCouponId());
            order.setPlatformCouponId(vo.getPlatformCoupon().getCouponId());
            order.setPlatformCouponName(vo.getPlatformCoupon().getCouponName());
            order.setPlatformCouponFaceValue(vo.getPlatformCoupon().getCouponFaceValue());
            order.setPlatformCouponSharing(vo.getPlatformCouponSharing());
        }

        if(vo.getShopCoupon().getMyCouponId()>0L)
        {
            order.setShopMyCouponId(vo.getShopCoupon().getMyCouponId());
            order.setShopCouponId(vo.getShopCoupon().getCouponId());
            order.setShopCouponName(vo.getShopCoupon().getCouponName());
            order.setShopCouponFaceValue(vo.getShopCoupon().getCouponFaceValue());
            order.setShopCouponResultValue(vo.getShopCoupon().getCouponResultValue());
        }

        orderService.create(order);
        if(vo.getPlatformCoupon().getMyCouponId()>0L)
        {
            couponReceiveRecordService.useCoupon(userId,order.getPlatformMyCouponId(),order.getId(),order.getOrderCode(),order.getPlatformCouponSharing());
        }

        if(vo.getShopCoupon().getMyCouponId()>0L)
        {
            couponReceiveRecordService.useCoupon(userId,order.getShopMyCouponId(),order.getId(),order.getOrderCode(),order.getShopCouponResultValue());
        }

        return order;

    }


    /**
     * 计算一个店铺下的订单的所有商品的运费合计
     *
     * @param shopId
     * @param receipt
     * @param childOrderVoList
     * @return
     */
    @Override
    public BigDecimal processFreight(Long shopId, SubmitOrderReceiptVo receipt, List<SubmitChildOrderVo> childOrderVoList) {
        LogisticsConfig logisticsConfig = logisticsConfigService.getLogisticsConfig(shopId);

        List<BigDecimal> fList = new ArrayList<>();
        Map<Integer, List<SubmitChildOrderVo>> collect = childOrderVoList.stream().collect(Collectors.groupingBy(SubmitChildOrderVo::getFreightTemplateId));
        collect.entrySet().stream().forEach(o -> {
            Integer freightTemplateId = o.getKey();
            FreightTemplate ft = freightTemplateService.getById(freightTemplateId);
            if (ft != null) {
                if(ft.getFreePost())
                {
                    fList.add(BigDecimal.ZERO);
                }
                else
                {
                    Integer total = o.getValue().stream().mapToInt(SubmitChildOrderVo::getNum).sum();
                    BigDecimal totalWeight = MathUtils.setScale(o.getValue().stream().mapToDouble(c -> c.getTotalWeight().doubleValue()).sum());
                    BigDecimal totalVolume = MathUtils.setScale(o.getValue().stream().mapToDouble(c -> c.getTotalVolume().doubleValue()).sum());
                    BigDecimal freight = ft.calculateFreight(receipt.getProvinceCode(), receipt.getCityCode(), total, totalWeight, totalVolume);
                    fList.add(freight);
                }

            }
        });

        OrderConstant.FreightStrategy freightStrategy = OrderConstant.FreightStrategy.SUPERIMPOSED;
        if (logisticsConfig != null) {
            freightStrategy = logisticsConfig.getFreightStrategy();
        }
        BigDecimal total = BigDecimal.ZERO;
        if (fList.size() > 0) {
            switch (freightStrategy) {
                case LOWEST:
                    total = fList.stream().min(BigDecimal::compareTo).get();
                    break;
                case HIGHEST:
                    total = fList.stream().max(BigDecimal::compareTo).get();
                    break;
                default:
                    double sum = fList.stream().mapToDouble(BigDecimal::doubleValue).sum();
                    total = BigDecimal.valueOf(sum);
                    break;
            }
        }
        return total;
    }


}
